<?php
/**
 * RedCross Application
 *
 * @copyright Copyright (c) 2010, Kristian Stokke Tryggestad, Rune Vikestad, Andreas Flaten Wist, Simen Nicolai Echholt, Ole Henrik Jahren
 */

/**
 * Abstract gateway class
 *
 * @category    RedCross
 * @package     RedCross_Gateway
 */
abstract class RedCross_Gateway_GatewayAbstract implements RedCross_Gateway_GatewayInterface
{

    /**
     * Path to model classes
     * @var string
     */
    protected $_modelPath;

    /**
     * Which class to instantiate
     * @var string
     */
    protected $_class;

    /**
     * The name of the primary key in the table
     * @var string
     */
    protected $_primaryKey = 'id';

    /**
     * Retrieve the name of the model class this gateway belongs to
     * @return string
     */
    protected function getModelClass()
    {
        return $this->_modelPath . '_' . $this->_class;
    }

    /**
     * Retrieve the name of the primary key of the table
     * @return string
     */
    protected function getPrimaryKey()
    {
        return $this->_primaryKey;
    }

    /**
     * Method for creating a new record in the database
     * @param array $data
     * @return a model class containing the saved values
     */
    public function create(array $data = array())
    {
        $class = $this->getModelClass();
        $class = new $class($data);
        return $this->save($class);
    }

    /**
     * Method for saving a record
     */
    public function save($data)
    {

        $modelClass = $this->getModelClass();
        if (!is_object($data) || !$data instanceof $modelClass) {
            throw new RedCross_Gateway_Exception("Incorrect datatype on the given argument. Should a object of type {$this->getModelClass()}");
        }

        try {
        	$data->save();
        } catch (Doctrine_Validator_Exception $e) {
            throw new RedCross_Gateway_ValidationException($e->getMessage());
        }

        return $data;
    }

    public function delete($data)
    {
        $modelClass = $this->getModelClass();
        if (!is_object($data) || !$data instanceof $modelClass) {
            throw new RedCross_Gateway_Exception("Incorrect datatype on the given argument. Should a object of type {$this->getModelClass()}");
        }
        try {
        	$data->delete();
        } catch (Doctrine_Validator_Exception $e) {
            throw new RedCross_Gateway_ValidationException($e->getMessage());
        }
        return true;
    }

    public function fetch($primary = null)
    {
        if (is_int($primary)) {
        	$record = Doctrine_Query::create()
        	   ->from($this->getModelClass() . ' o')
        	   ->where("o.{$this->getPrimaryKey()} = ?", $primary)
        	   ->fetchOne();
            if ($record) return $record;

        } else if (is_array($primary)) {
        	foreach ($primary as $v) {
        		if (!is_int($v)) {
        			throw new RedCross_Gateway_Exception(__CLASS__ . '::' . __METHOD__ . ': All members of given array should be int-values');
        		}
        	}

            $records = Doctrine_Query::create()
        	   ->from($this->getModelClass() . ' o')
        	   ->whereIn('o.' . $this->getPrimaryKey(), $primary)
        	   ->execute();
            return $records;
        } else {
            throw new RedCross_Gateway_Exception(__CLASS__ . '::' . __METHOD__ . ': Parameter should be an int or an array');
        }
    }

    public function fetchAll($paginate = false) {
    	$query = Doctrine_Query::create()
           ->from($this->getModelClass() . ' o');

        return $paginate ? new RedCross_Paginator($query) : $query->execute();
    }
//
//    public function count()
//    {
//        ;
//    }
}